all: core | extract_info

include ../prtos_config
include $(PRTOS_PATH)/config.mk
include $(PRTOS_PATH)/core/rules.mk

ifdef CONFIG_MMU
	MM=mmu
else 
	MM=
endif

ifeq ($(PRTOS_PATH)/core/.config, $(wildcard $(PRTOS_PATH)/core/.config))
	exists_config := 1
endif

$(if $(exists_config), $(if $(MM),, $(error "MM variable is not defined")))

PEF=$(PRTOS_PATH)/user/bin/prtoseformat

$(PEF):
	make -C $(PRTOS_PATH)/user/tools/pef install

prtos.lds: kernel/$(ARCH)/prtos.lds.in include/config.h
	@$(TARGET_CC) $(TARGET_ASFLAGS) -x assembler-with-cpp -E -P -I$(PRTOS_CORE_PATH)/include kernel/$(ARCH)/prtos.lds.in -o kernel/$(ARCH)/prtos.lds

PRTOSCORE_SUBDIRS=\
	kernel/$(ARCH)\
	kernel/$(MM)\
	kernel\
	klibc klibc/$(ARCH)\
	objects drivers\

KOBJS=\
	build_info.o\
	pbl.o\
	kernel/$(ARCH)/karch.o\
	kernel/$(MM)/kmm.o\
	kernel/kern.o\
	klibc/libc.o\
	klibc/$(ARCH)/arch_libc.o\
	objects/objects.o drivers/drivers.o\

links:
	@exec echo -e "\n> Target architecture: [$(ARCH)] ";
	@if [ ! -d $(PRTOS_PATH)/core/include/arch ] ; then \
		ln -sf $(PRTOS_PATH)/core/include/$(ARCH) $(PRTOS_PATH)/core/include/arch; \
	fi

Kconfig.ver:
	@exec echo "# $@: autogenerated file, don't edit"		>  $@
	@exec echo "config ARCH"					>> $@
	@exec echo "	string"						>> $@
	@exec echo "	default \"$(ARCH)\""				>> $@

	@exec echo "" >> $@
	@exec echo "config KERNELVERSION"				>> $@
	@exec echo "	string"						>> $@
	@exec echo "	default \"$$PRTOSVERSION\""			>> $@

	@exec echo "" >> $@
	@exec echo "config PRTOS_VERSION" >> $@
	@exec echo "	int"						>> $@
	@exec echo "	default $$PRTOS_VERSION"	>> $@
	@exec echo "config PRTOS_SUBVERSION" >> $@
	@exec echo "	int"						>> $@
	@exec echo "	default $$PRTOS_SUBVERSION"	>> $@
	@exec echo "config PRTOS_REVISION" >> $@
	@exec echo "	int"						>> $@
	@exec echo "	default $$PRTOS_REVISION"	>> $@

KCONFIG=kernel/$(ARCH)/Kconfig

user_links:
	@make -C $(PRTOS_PATH)/user links

config: links Kconfig.ver
	@$(PRTOS_PATH)/scripts/kconfig/conf $(KCONFIG)

oldconfig: links Kconfig.ver
	@$(PRTOS_PATH)/scripts/kconfig/conf -o $(KCONFIG)

silentoldconfig: links Kconfig.ver
	@mkdir -p $(PRTOS_PATH)/core/include/config
	@$(PRTOS_PATH)/scripts/kconfig/conf -s $(KCONFIG)

menuconfig: links Kconfig.ver
	@$(PRTOS_PATH)/scripts/kconfig/mconf $(KCONFIG)

$(defconfig-targets): links Kconfig.ver
	@$(PRTOS_PATH)/scripts/kconfig/conf -D $(PRTOS_PATH)/core/kernel/$(ARCH)/$@ $(KCONFIG)
defconfig: 

#$(PRTOS_PATH)/core/include/autoconf.h: $(PRTOS_PATH)/core/.config silentoldconfig

pbl/pbl.bin:
	@$(MAKE) -s -C pbl

core: pbl/pbl.bin $(PRTOS_PATH)/core/include/autoconf.h prtos.lds generate_offsets build.info user_links $(PEF)
	@$(PRTOS_PATH)/scripts/gencomp.pl $(PRTOS_PATH)/core/include/comp.h
	@exec echo -e "\n> Building PRTOS Core";
	@for dir in $(PRTOSCORE_SUBDIRS) ; do \
		echo "  - $$dir"	; \
		$(MAKE) -s -C $$dir all  ; \
		if [ "$$?" -ne 0 ]; then exit 1 ; fi \
	done
	@exec echo "" | $(TARGET_CC) $(TARGET_CFLAGS) -x c -c - -o build_info.o
	@$(TARGET_OBJCOPY) --add-section .build_info=build.info build_info.o
	@exec echo "" | $(TARGET_CC) $(TARGET_CFLAGS) -x c -c - -o pbl.o
	@$(TARGET_OBJCOPY) --add-section .pbl=pbl/pbl.bin --set-section-flags .pbl=alloc pbl.o
	@exec echo -e "> Linking PRTOS Core";
	@$(TARGET_LD) $(TARGET_LDFLAGS) -nostdlib -Tkernel/$(ARCH)/prtos.lds -o prtos_core $(KOBJS) $(LIBGCC) ;
	@$(TARGET_SIZE) prtos_core;
ifdef CONFIG_PEF_COMPRESSION
	@$(PEF) build prtos_core -c -o prtos_core.pef
else
	@$(PEF) build prtos_core -o prtos_core.pef
endif
	@chmod -x prtos_core
	@exec echo "> Done";

build.info:
	@exec echo "BUILD_TARGET_CC=\"`($(TARGET_CC) --version | head -1)`\"" > build.info;
	@exec echo "BUILD_TIME=\"`(LANG="C" date)`\"" >> build.info;
	@exec echo "BUILD_HOST=\"`(hostname)`\"" >> build.info;
	@exec echo "BUILD_UID=\"`(id -nu)`\"" >> build.info;
	@grep ^CONFIG_* .config >> build.info;

generate_offsets:
	@$(TARGET_CC) $(TARGET_CFLAGS) -S -o offsets.S $(PRTOS_PATH)/scripts/asm-offsets.c -D_GENERATE_OFFSETS_ -D_OFFS_FILE_=\"$(ARCH)/gen_offsets.h\"
	@$(SHELL) $(PRTOS_PATH)/scripts/asm-offsets.sh offsets.h < offsets.S > $(PRTOS_CORE_PATH)/include/$(ARCH)/asm_offsets.h
	@$(RM) -f offsets.S

extract_info:
	@$(HOST_CC) -Wall -O2 -o $(PRTOS_PATH)/scripts/extractinfo $(PRTOS_PATH)/scripts/extractinfo.c -DTARGET_OBJCOPY=\"$(TARGET_OBJCOPY)\" --include $(PRTOS_PATH)/core/include/autoconf.h
	@$(PRTOS_PATH)/scripts/extractinfo $(PRTOS_PATH)/core/prtos_core 2> $(PRTOS_CORE_PATH)/include/$(ARCH)/ginfo.h

clean:
	@exec echo -e "> Cleaning PRTOS Core";
	@exec echo -e "  - Removing *.o *.a *~ files";
	@find -name "*~" -exec rm '{}' \;
	@find -name "*.o" -exec rm '{}' \;
	@find -name "*.xo" -exec rm '{}' \;
	@find -name "*.a" -exec rm '{}' \;
	@$(RM) -f kernel/$(ARCH)/prtos.lds include/$(ARCH)/asm_offsets.h include/$(ARCH)/ginfo.h include/$(ARCH)/brksize.h build.info prtos_core prtos_core.bin prtos_core.pef pbl/*.elf pbl/*.bin pbl/*.lds
	@exec echo -e "> Done";
